<?php

declare(strict_types=1);

namespace think\seecms;

use seecms\See;
use seecms\SeeException;
use seecms\SeeResponse;
use think\helper\Str;
use think\Response;

/**
 * 资源调度器
 */
class Dispatch extends \think\route\Dispatch
{

    /**
     * @throws SeeException
     */
    public function exec()
    {
        $controller = $this->request->route('controller');
        $action = $this->request->route('action');

        if (empty($controller)) {
            $path_info = explode('/', $this->request->pathinfo());
            $controller = $path_info[0] ?? '';
            if (empty($action)) {
                $action = $path_info[1] ?? '';
            }
        }

        $controller = Str::studly($controller);
        $action = Str::camel($action);

        $class = See::controller($controller);
        if (!method_exists($class, $action)) {
            throw new SeeException(sprintf('The %s method of the %s class does not exist', $action, class_basename($class)));
        }

        /**
         * @var SeeResponse $response
         */
        $response = $class->$action();
        if ($response instanceof SeeResponse) {
            return Response::create($response->data, $response->type, $response->status_code)->header($response->header);
        }

        if (is_array($response)) {
            return Response::create($response, 'json');
        }

        return Response::create($response);
    }
}